// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
}) // 使用当前云环境

const db = cloud.database()
const _ = db.command

const saleStts = {
  stts: {},
  shop: 'all',
  delivery: [],
  order2shop: {},
  async doStts(start, end, shop) {
    this.shop = shop
    this.stts = this.order2shop = {}
    const orders = await saleStts.loadAllOrders(start, end)
    // console.log(orders)
    if (shop != 'all') {
      // const res = await this.getDeliveryUsers()
      // this.delivery = res.data
      // console.log(this.delivery)
      await this.mapOrder2Shop(orders)
    }
    await this.calculate(orders)
    this.postCalc()
    return this.stts
  },
  async calculate(orders) {
    for (const order of orders) {
      if (!this.matchOrder(order)) continue;
      this.totalSale(order)
      this.ticketSale(order)
      this.deliSale(order)
      this.goodsSale(order)
    };
  },
  async loadAllOrders(start, end) {
    const MAX_LIMIT = 100
    // 先取出集合记录总数
    const where = {
      payStatus: _.eq('success'),
      status: _.neq('已取消'),
      createTime: _.and(_.gte(start), _.lte(end))
    }
    const countResult = await db.collection('orders').where(where).count()
    const total = countResult.total
    // 计算需分几次取
    const batchTimes = Math.ceil(total / 100)
    // 承载所有读操作的 promise 的数组
    const tasks = []
    for (let i = 0; i < batchTimes; i++) {
      const promise = db.collection('orders').where(where).field({
        _id: true,
        _openid: true,
        createtime: true,
        status: true,
        totalFee: true,
        ticketOrderId: true,
        ticketInfo: true,
        refoundInfo: true,
        deliveryMan: true,
        goodsList: true
      }).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
      tasks.push(promise)
    }
    // 等待所有
    return (await Promise.all(tasks)).reduce((acc, cur) => {
      return {
        data: acc.data.concat(cur.data),
        errMsg: acc.errMsg,
      }
    }).data
  },
  postCalc() {
    for (const key of Object.keys(this.stts)) {
      if (key == 'goods') continue
      for (const skey of Object.keys(this.stts[key])) {
        const val = this.stts[key][skey]
        this.stts[key][skey] = this.readableNum(val)
      }
    }
  },
  readableNum(num) {
    const val = Number(num)
    if (val >= 10000) {
      return Number(val / 10000).toFixed(0) + '万零' + this.fixNum(val % 10000)
    }
    return this.fixNum(val)
  },
  fixNum(num) {
    let val = num.toFixed(2)
    if (val.endsWith(".00")) val = Number(num).toFixed(0)
    return val
  },
  matchOrder(order) {
    if (this.shop == 'all') return true;
    // console.log(this.order2shop)
    // console.log(order._openid)
    return this.order2shop[order._openid] > 0
  },
  async getDeliveryUsers() {
    if (this.shop == 'all') return
    this.shop = parseInt(this.shop)
    const res = await db.collection('users').where({
        role: _.eq('delivery').or(_.eq('master')),
        'shop.id': _.eq(this.shop)
      })
      .field({
        _openid: true,
        shop: true
      }).get()
    // console.log(res)
    return res
  },
  async mapOrder2Shop(orders) {
    const MAX_LIMIT = 100
    // 先取出集合记录总数
    const openids = []
    for (const o of orders) openids.push(o._openid)
    const where = {
      _openid: _.in(openids),
      shop: _.eq(String(this.shop))
    }
    const countResult = await db.collection('delivery_addr').where(where).count()
    const total = countResult.total
    console.log(total)
    if (total == 0) return {}

    // 计算需分几次取
    const batchTimes = Math.ceil(total / 100)
    // 承载所有读操作的 promise 的数组
    const tasks = []
    for (let i = 0; i < batchTimes; i++) {
      const promise = db.collection('delivery_addr').where(where).field({
        shop: true,
        _openid: true
      }).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
      tasks.push(promise)
    }
    // 等待所有
    const res = (await Promise.all(tasks)).reduce((acc, cur) => {
      return {
        data: acc.data.concat(cur.data),
        errMsg: acc.errMsg,
      }
    })

    for (const m of res.data) {
      this.order2shop[m._openid] = parseInt(m.shop)
    }
    console.log(this.order2shop)
    return this.order2shop
  },
  totalSale(order) {
    if (order.ticketInfo) return
    this.stts.total = this.stts.total || {
      netSales: 0,
      total: 0,
      refound: 0
    }
    const t = this.stts.total
    t.total += Number(order.totalFee || 0)
    t.netSales += Number(order.totalFee || 0)
    if (order?.refoundInfo?.status == 'success') {
      t.refound += Number(order.refoundInfo.fee)
      t.netSales -= Number(order.refoundInfo.fee)
    }
  },
  ticketSale(order) {
    if (!order.ticketInfo) return
    this.stts.ticket = this.stts.ticket || {
      netSales: 0,
      total: 0,
      refound: 0,
      num: 0,
      used: 0
    }
    const t = this.stts.ticket
    t.total += Number(order.totalFee || 0)
    t.netSales += Number(order.totalFee || 0)
    if (order?.refoundInfo?.status == 'success') {
      t.refound += Number(order.refoundInfo.fee || 0)
      t.netSales -= Number(order.refoundInfo.fee || 0)
    }
    t.num += order.ticketInfo.totalAmount || 0
    t.used += order.ticketInfo.used || 0
  },
  deliSale(order) {
    const s = order.status
    if (s != '已送达' && s != '已退款') return
    this.stts.deliTicket = this.stts.deliTicket || {
      netSales: 0,
      total: 0,
      refound: 0
    }
    this.stts.deliBuy = this.stts.deliBuy || {
      netSales: 0,
      total: 0,
      refound: 0
    }
    this.stts.deli = this.stts.deli || {
      netSales: 0
    }
    const t = order.ticketOrderId ? this.stts.deliTicket : this.stts.deliBuy;
    const fee = Number(order.totalFee || 0)
    let refound = 0
    t.total += fee
    t.netSales += fee
    if (order.refoundInfo?.status == 'success') {
      refound = Number(order.refoundInfo.fee)
      t.refound += refound
      t.netSales -= refound
    }
    this.stts.deli.netSales += (fee - refound)
  },
  goodsSale(order) {
    if (order.ticketInfo) return

    const goods = this.stts.goods = this.stts?.goods || {}
    // console.log(order)
    if (!order.goodsList?.[0]) return

    const {
      spuId,
      title,
      num
    } = order.goodsList[0]

    const item = {
      title,
      num,
      gift: order.ticketInfo?.gift || 0
    }
    const gitem = goods[spuId] = goods[spuId] || {
      id: spuId,
      title: '',
      num: 0,
      gift: 0
    }
    // console.log(this.stts.goods)
    gitem.title = title
    gitem.num += Number(item.num)
    gitem.gift += Number(item.gift)
  }
}
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const {
    start,
    end,
    shop
  } = event
  const stts = await saleStts.doStts(start, end, shop)
  return {
    stts
  }
}